using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PlayerInput : MonoBehaviour {
	private PlayerLogic logic;

	//debug command members
	public SpawnPoint EnemySpawner = null;
	public bool InvertHorizontal = false;
	public bool InvertVertical = false;
	private float attackLifetime = 0;

	// Use this for initialization
	void Start () {
		logic = GetComponent<PlayerLogic>();
		ReloadActor();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void FixedUpdate()
	{
		//we can't do movement or weapon control if we're dead
		if(logic.Health.IsAlive)
		{
			updateMovementInput();
			updateWeaponInput();
			attackLifetime -= Time.fixedDeltaTime;
		}
		
		//next, handle debug mode commands and menu if necessary
		updateDebugInput();
	}

	/*
	protected void updateRaycast () {
		//always do a raycast
		if(actorCamera != null)
		{
			Ray cast = actorCamera.ControlledCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
			RaycastHit hit = new RaycastHit(); //Raycast test will store an hit information here
			if(Physics.Raycast(cast, out hit) && hit.distance <= actorCtrl.MaxLockOnDistance)
			{
				AlignmentDistance = hit.distance;
				//tags are on parents of collider objects, so search up the hit's parent tree for a tagged object
				lockOnTarget = ParentSearches.FindParentWithTag(hit.collider.transform, "LockOnTarget");
				//print("TESTING lockONTarget: "+lockOnTarget.position);
			}
		}
	}
	*/

	protected void updateMovementInput()
	{
		//compose the velocity vector first
		//...a little easier than I thought it'd be
		Vector3 moveVector = new Vector3((InvertHorizontal ? -1 : 1) * Input.GetAxis("Horizontal"), 
		                     			0,
		                                 (InvertVertical ? -1 : 1) * Input.GetAxis("Vertical"));
		//if needed, renormalize the movement vector
		if(moveVector.sqrMagnitude > 1.0f)
		{
			moveVector.Normalize();
		}
		
		//and then give the movement order to the actor
		logic.Actor.Move(moveVector);
	}

	protected void updateWeaponInput()
	{
		//If the attack button was pressed, spawn the weapon in the given direction.
		if (Input.GetButtonDown ("Attack") && logic.CurrWeapon != null)
		{
			Weapon currWeapon = logic.CurrWeapon;
			if(attackLifetime <= 0)
			{
				Weapon wepInstance = (Weapon)Instantiate(currWeapon);
                Transform actorTrans = logic.Actor.transform;
                wepInstance.Owner = actorTrans;
				Transform wepTrans = wepInstance.transform;
                Vector3 wepDir = (logic.Actor.Heading.sqrMagnitude > 0 ?
                                            -logic.Actor.Heading * wepInstance.Size :
                                            -Vector3.forward * wepInstance.Size);
                Vector3 wepOffset = wepDir + Vector3.up * 0.5f;
                //If this is a melee weapon, place it relative to the character.
                if (wepInstance.WeaponVelocity <= 0)
                {
                    wepTrans.parent = transform;
                    wepTrans.localPosition = wepOffset;
                }
                //Otherwise, place it relative to the world but originating from the character.
                else
                {
                    wepTrans.position = actorTrans.position + wepOffset;
                }
                //Also give a attack direction; some melee weapons may have knockback.
                wepInstance.AttackDirection = wepDir;
				attackLifetime = currWeapon.Lifetime;
			}
		}
	}

	public void ReloadActor()
	{
		//if the logic script reports that we've got a new actor, continue
		if(logic.Actor != null)
		{
			ActorController actor = logic.Actor;
		}
		else
		{
			//if we didn't attach to a new actor, something's gone wrong
			print("PlayerInput: can't find new actor!");
		}
	}

	void updateDebugInput ()
	{
		/*
		if(Input.GetButtonDown("ToggleAI"))
		{
			AIManager.GetInstance().ToggleAgentsEnabled();
		}
		if(Input.GetButtonDown("SpawnEnemy"))
		{
			//have we been passed an enemy spawner?
			if(EnemySpawner != null)
			{
				EnemySpawner.Spawn();
			}
		}
		*/
	}
}
